home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dskut
/
xlat11.zip
/
XLAT.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-10-19
|
10KB
|
273 lines
; XLAT.ASM -- configurable char-to-char file converter
;
; Freeware by TapirSoft Gisbert W.Selke, Oct 89
;
; TASM xlat
; TLINK /T xlat
Tab Equ 09h
Return Equ 0Dh
LineFeed Equ 0Ah
CtrlZ Equ 1Ah
CSEG Segment
Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
Org 0000h
CSegOfs Label Byte ; start of core image
Org 0080h
CmdLine Label Byte
Org 0100h
Entry: Jmp Begin
;
; Data:
;
ProgInfo db Low(Offset ProgVersion) ; file offset of patch info
ProgName db Return, 'Configurable text file converter'
CopyRight db Return, LineFeed
db 'FreeWare by TapirSoft Gisbert W.Selke, Oct 1989'
db Return, LineFeed
Marker1 db '<<<< ' ; marker for patches
Description db 'Identity mapping as a starting point '
; the length of the preceding string should remain at 40!
Marker2 db ' >>>>', CtrlZ ; marker for patches
EndHeader Label Byte
ProgVersion db 'XLAT10' ; standard name and version
DescOff db Low(Offset Description) ; file offset of descr. text
DescLength db Marker2-Description ; length of description text
InterNameOff dw (Offset InterName)-100h ; file offset of usage text
MainTableOff dw MainTable-100h ; file offset of main table
; the next few lines fill the 'default' translation table with the identity
; mapping:
MainTable Label Byte
outcode = 0
Rept 256
db outcode
outcode = outcode + 1
EndM
MainTableEnd Label Byte
InverseFlag db 0 ; 0 = normal; 1 = inverse
ReadErrString db 'Error reading from file', Return, LineFeed
ReadErrEnd Label word
WriteErrString db 'Error writing to file', Return, LineFeed
WriteErrEnd Label word
Begin: Cld ; All string directions forward
Call ParseArgs ; scan command line
Cmp InverseFlag, 0FFh ; illegal parrameter?
Je Usage ; skip if so
Cmp InverseFlag, 1 ; use inverted table?
Je UseInverse ; skip if so
Mov bx, Offset MainTable ; else use table as specified
Push bx ; put on stack
Jmp Short NextBuffer
UseInverse: Call BuildInverse ; build inverse table
Mov bx, Offset InverseTable ; use inverted table
Push bx ; put address on stack
NextBuffer: Mov ah, 3Fh ; read buffer from stdin
Xor bx, bx
Mov cx, BufferLength
Mov dx, offset Buffer
Mov si, dx ; jot down for later use
Mov di, dx ; ditto
Int 21h
Jc ReadError ; jump if error on read
Or ax, ax
Jz FinishIt ; jump to end if no chars read
Pop bx ; get back tranlation table address
Mov cx, ax ; number of chars actually read
Mov dx, ax ; also, save for later use
ProcChar: Lodsb ; process characters
Xlat ; translate according to table
Stosb ; stuff it back in
Loop ProcChar ; process next character, if available
Push bx ; otherwise save table address
Mov ah, 40h
Mov bx, 1 ; write to stdout
Mov cx, dx ; get back number of characters
Mov dx, offset Buffer
Int 21h
Jc WriteError
Cmp ax, cx
Jne WriteError
Jmp short NextBuffer ; get next buffer
;
; Handle read error:
;
ReadError: Mov dx, Offset ReadErrString
Mov cx, ReadErrEnd-ReadErrString
Mov ah, 40h ; output message to stderr
Mov bx, 2
Int 21h
Pop bx ; remove table address from stack
Mov al, 02h ; set error flag
Jmp Short Terminate
;
; Handle write error:
;
WriteError: Mov dx, Offset WriteErrString
Mov cx, WriteErrEnd-WriteErrString
Mov ah, 40h ; output message to stderr
Mov bx, 2
Int 21h
Pop bx ; remove table address from stack
Mov al, 03h ; set error flag
Jmp Short Terminate
;
; show usage screen:
;
Usage: Mov dx, Offset ProgName ; display programme header
Mov cx, ProgName-EndHeader
Mov ah, 40h ; output message to stderr
Mov bx, 2
Int 21h
Mov dx, Offset UsageText ; display usage screen
Mov cx, UsageEnd-UsageText
Mov ah, 40h ; output message to stderr
Int 21h
Mov al, 01h
Jmp Short Terminate
;
; We are done.
;
FinishIt: Pop bx ; remove table address from stack
Xor al, al ; set no-error flag
Jmp Short Terminate
;
; Terminate
;
Terminate: Mov ah, 4Ch ; error flag was set elsewhere
Int 21h ; Terminate
;
; Subroutines:
;
BuildInverse Proc Near
;
; Build inverse mapping table as well as we can.
; Scan backwards; we assume that in case of non-injectivity,
; the preferrred values are the lower character codes
; (i.e., choose the lowest pre-image).
; (Just as well as any other assumption, but easier to imagine)
;
Mov di, Offset InverseTable ; point to inverse table
Xor ax, ax ; initialization value: 0
Mov cx, 256 ; length of table
Rep Stosb ; fill table
Std ; scan original table backward
Mov si, Offset MainTableEnd - 1; point to end of original table
Mov cx, 256 ; length of table
Xor dl, dl ; set dl to 'last char'
; Xor ax, ax ; ax is still 0
BINext: Lodsb ; get next table entry
Mov di, ax
Dec dl
Mov byte ptr [di+InverseTable], dl; Table[Maintable[dl]] <- dl
Loop BINext
Cld ; scan forward again
Ret
EndP BuildInverse
ParseArgs Proc Near
;
; scan command line for arguments; only arguments supported:
; /i : use inverse mapping
; anything else : usage screen (sent to stderr)
;
Mov si, Offset CmdLine + 1 ; point to command line
PANext: Lodsb ; get next char
Cmp al, Return ; at end?
Je PADone ; if so, finish